package club.ruanx.movie.controller;

import club.ruanx.acl.common.exception.UserException;
import club.ruanx.bean.PageBean;
import club.ruanx.bean.ResultVO;
import club.ruanx.core.exception.TargetEntityNotFound;
import club.ruanx.movie.controller.vo.UserFavoriteRecordVO;
import club.ruanx.movie.controller.vo.UserRateRecordVO;
import club.ruanx.movie.entity.Movie;
import club.ruanx.movie.entity.UserFavorite;
import club.ruanx.movie.entity.UserRate;
import club.ruanx.movie.service.MovieService;
import club.ruanx.movie.service.UserFavoriteService;
import club.ruanx.movie.service.UserRateService;
import club.ruanx.security.bean.UserAuthInfo;
import club.ruanx.security.bean.UserAuthInfoContextHolder;
import club.ruanx.util.PagingUtils;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 阮胜
 * @date 2018/12/15 15:21
 */
@RestController
@RequestMapping("/movie/user")
public class MovieUserController {
    private final UserRateService userRateService;
    private final MovieService movieService;
    private final UserFavoriteService userFavoriteService;

    public MovieUserController(UserRateService userRateService, MovieService movieService, UserFavoriteService userFavoriteService) {
        this.userRateService = userRateService;
        this.movieService = movieService;
        this.userFavoriteService = userFavoriteService;
    }

    @GetMapping("/info")
    public ResultVO authInfo() throws UserException {
        UserAuthInfo authInfo = UserAuthInfoContextHolder.getCurrentUserAuthInfoThrow();
        return ResultVO.builder().success(true).data(authInfo).build();
    }

    @GetMapping("/rate/records")
    @PreAuthorize("hasAnyRole('USER')")
    public List<UserRateRecordVO> rateRecords(PageBean pageBean) throws UserException {
        String uid = UserAuthInfoContextHolder.getCurrentUserAuthInfoThrow().getUid();
        Page<UserRate> userRateRecordPage = userRateService.findAllByUserId(uid, pageBean);
        PagingUtils.setNgxAdminPagingHeader(userRateRecordPage.getTotalElements());
        return userRateRecordPage.getContent().stream()
                .map(userRate -> {
                    UserRateRecordVO userRateRecordVO = new UserRateRecordVO();
                    userRateRecordVO.setUserRate(userRate);
                    try {
                        Movie movie = movieService.findById(userRate.getMovieId());
                        userRateRecordVO.setMovie(movie);
                    } catch (TargetEntityNotFound targetEntityNotFound) {
                        targetEntityNotFound.printStackTrace();
                    }
                    return userRateRecordVO;
                }).filter(userRateRecordVO -> userRateRecordVO.getMovie() != null)
                .collect(Collectors.toList());
    }

    @GetMapping("/favorite/records")
    @PreAuthorize("hasAnyRole('USER')")
    public List<UserFavoriteRecordVO> favoriteRecordVOS(PageBean pageBean) throws UserException {
        String uid = UserAuthInfoContextHolder.getCurrentUserAuthInfoThrow().getUid();
        Page<UserFavorite> userFavoritePage = userFavoriteService.findAllByUserId(uid, pageBean);
        PagingUtils.setNgxAdminPagingHeader(userFavoritePage.getTotalElements());
        return userFavoritePage.getContent().stream()
                .map(userFavorite -> {
                    UserFavoriteRecordVO record = new UserFavoriteRecordVO();
                    record.setUserFavorite(userFavorite);
                    try {
                        Movie movie = movieService.findById(userFavorite.getMovieId());
                        record.setMovie(movie);
                    } catch (TargetEntityNotFound targetEntityNotFound) {
                        targetEntityNotFound.printStackTrace();
                    }
                    return record;
                }).filter(userFavoriteRecordVO -> userFavoriteRecordVO.getMovie() != null)
                .collect(Collectors.toList());
    }
}
